package cameraTool;
import java.io.IOException;

import java.io.BufferedOutputStream;  
import java.io.File;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.nio.ByteBuffer;  
import java.text.SimpleDateFormat;  
import java.util.Date;  

import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.NativeLongByReference;

import cameraTool.HCNetSDK.NET_DVR_DEVICEINFO_V30;  
import cameraTool.HCNetSDK.NET_DVR_IPPARACFG;  
import cameraTool.HCNetSDK.NET_DVR_JPEGPARA;  
import cameraTool.HCNetSDK.NET_DVR_WORKSTATE_V30;  

public class TestHikvision {  
    
    public static void main(String[] args) throws IOException {  
        TestHikvision app = new TestHikvision();  
          
        MonitorCameraInfo cameraInfo = new MonitorCameraInfo();//需要新建MonitorCameraInfo类  
        cameraInfo.setCameraIp("183.63.160.181");  
        cameraInfo.setCameraPort(8000);  
        cameraInfo.setUserName("admin");  
        cameraInfo.setUserPwd("qq123456");  
          
        app.getDVRConfig(cameraInfo);  
        app.getDVRPic(cameraInfo);  
        //app.Test_CaptureJpegPicture_new(cameraInfo);  
    }  
  
    public void getDVRConfig(MonitorCameraInfo cameraInfo) {  
        HCNetSDK sdk = HCNetSDK.INSTANCE;  
        //判断摄像头是否开启  
        if (!sdk.NET_DVR_Init()) {  
            System.out.println("SDK初始化失败");  
            return;  
        }  
        //设置连接时间与重连  
        //sdk.NET_DVR_SetConnectTime(2000, 1);    
        //sdk.NET_DVR_SetReconnect(10000, true);  
  
        NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息  
          
        //System.out.println("设备信息："+devinfo);  
          
        //登录信息  
        NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(),  
                cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo);  
  
        cameraInfo.setUserId(id);// 返回一个用户编号，同时将设备信息写入devinfo  
        //输出int数据  
        //System.out.println("intValue:"+cameraInfo.getUserId().intValue());  
        if (cameraInfo.getUserId().intValue() < 0) {  
            System.out.println("设备注册失败");  
            return;  
        }  
        //DVR工作状态  
        NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30();  
        if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) {  
            // 返回Boolean值，判断是否获取设备能力  
            System.out.println("返回设备状态失败");  
        }  
  
        IntByReference ibrBytesReturned = new IntByReference(0);// 获取IP接入配置参数  
        NET_DVR_IPPARACFG ipcfg = new NET_DVR_IPPARACFG();//IP接入配置结构  
        ipcfg.write();  
        Pointer lpIpParaConfig = ipcfg.getPointer();  
        //获取相关参数配置  
        sdk.NET_DVR_GetDVRConfig(cameraInfo.getUserId(), HCNetSDK.NET_DVR_GET_IPPARACFG, new NativeLong(0),  
                lpIpParaConfig, ipcfg.size(), ibrBytesReturned);  
        ipcfg.read();  
        System.out.print("IP地址:" + cameraInfo.getCameraIp());  
        System.out.println("|设备状态：" + devwork.dwDeviceStatic);// 0正常，1CPU占用率过高，2硬件错误，3未知  
        //System.out.println("ChanNum"+devinfo.byChanNum);  
        // 显示模拟通道  
        for (int i = 0; i < devinfo.byChanNum; i++) {  
            System.out.print("Camera" + i + 1);// 模拟通道号名称  
            System.out.print("|是否录像:" + devwork.struChanStatic[i].byRecordStatic);// 0不录像，不录像  
            System.out.print("|信号状态:" + devwork.struChanStatic[i].bySignalStatic);// 0正常，1信号丢失  
            System.out.println("|硬件状态:" + devwork.struChanStatic[i].byHardwareStatic);// 0正常，1异常  
        }  
        //注销用户  
        sdk.NET_DVR_Logout(cameraInfo.getUserId());//释放SDK资源  
        sdk.NET_DVR_Cleanup();  
    }  
  
    //抓拍图片  
    public void getDVRPic(MonitorCameraInfo cameraInfo) throws IOException {  
          
        //设置通道号，其中1正常，-1不正常  
        NativeLong chanLong = new NativeLong(1);  
        cameraInfo.setChannel(chanLong);  
        //System.out.println("Channel:"+chanLong);  
        long startTime = System.currentTimeMillis();  
        HCNetSDK sdk = HCNetSDK.INSTANCE;  
        if (!sdk.NET_DVR_Init()) {  
            System.out.println("SDK初始化失败");  
            return;  
        }  
  
        NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息  
          
        //注册设备  
        NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(),  
                cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo);  
        cameraInfo.setUserId(id);// 返回一个用户编号，同时将设备信息写入devinfo  
        if (cameraInfo.getUserId().intValue() < 0) {  
            System.out.println("设备注册失败"+sdk.NET_DVR_GetLastError());  
            return;  
        } else {  
            System.out.println("id：" + cameraInfo.getUserId().intValue());  
        }  
        NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30();  
        if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) {  
            // 返回Boolean值，判断是否获取设备能力  
            System.out.println("返回设备状态失败");  
        }  
  
        //System.out.println("设备注册耗时：[" + (System.currentTimeMillis() - startTime) + "]");  
  
        startTime = System.currentTimeMillis();  
        //图片质量  
        NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA();  
        // 设置图片的分辨率  
        jpeg.wPicSize = 0;  
        // 设置图片质量  
        jpeg.wPicQuality = 9;  
  
        IntByReference a = new IntByReference();  
        //设置图片大小  
        ByteBuffer jpegBuffer = ByteBuffer.allocate(3072 * 2048);  
        // 创建文件目录，文件？？？？？  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");  
        Date date = new Date();  
        String fileNameString = "D:/CapturePicture/"+sdf.format(date)+".jpg";  
        //还需要设置抓拍图片格式  
/*      String pathString = cameraInfo.getFilePath();*/  
        File file = new File(fileNameString);  
/*        if (!file.exists()) {   
            file.mkdirs(); //创建目录 
        }*/  
        //file.mkdirs();  
  
  
        // 抓图到内存，单帧数据捕获并保存成JPEG存放在指定的内存空间中  
        //需要加入通道  
        boolean is = sdk.NET_DVR_CaptureJPEGPicture_NEW(cameraInfo.getUserId(), cameraInfo.getChannel(), jpeg,  
                jpegBuffer, 3072 * 2048, a);  
        //System.out.println("Channel:"+cameraInfo.getChannel());  
        System.out.println("抓图到内存耗时：[" + (System.currentTimeMillis() - startTime) + "ms]");  
  
        // 抓图到文件  
        //boolean is = sdk.NET_DVR_CaptureJPEGPicture(cameraInfo.UserId,cameraInfo.Channel,jpeg, fileNameString);  
        if (is) {  
            System.out.println("抓取成功,返回长度：" + a.getValue());  
        } else {  
            System.out.println("抓取失败："+sdk.NET_DVR_GetLastError());  
        }  
  
        //startTime = System.currentTimeMillis();  
        // 存储本地，写入内容  
        BufferedOutputStream outputStream = null;  
        try {  
            outputStream = new BufferedOutputStream(new FileOutputStream(file));  
            outputStream.write(jpegBuffer.array(), 0, a.getValue());  
            outputStream.flush();  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            if (outputStream != null) {  
                try {  
                    outputStream.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
  
        //System.out.println("存储本地耗时：[" + (System.currentTimeMillis() - startTime) + "]");  
  
        sdk.NET_DVR_Logout(cameraInfo.getUserId());  
        sdk.NET_DVR_Cleanup();  
    }  
}  